<template>
  <!-- 最外层的容器 -->
  <section class="todoapp">
    <!-- 头部 -->
    <header class="header">
      <h1>代办事项</h1>
      <input type="text" class="new-todo" placeholder="添加新的待办事项" @keyup.ctrl.enter="addTodo">
    </header>
    <!-- 待办列表 -->
    <section class="main">
      <!-- 全选按钮 -->
      <input type="checkbox" id="toggle-all" class="toggle-all" />
      <label for="toggle-all">全部完成</label>
      <!-- 待办事项列表 -->
      <ul class="todo-list">
        <li v-for="(todo, index) in filteredTodos" :key="todo.id" :class="{
        completed: todo.completed,
        editing: todo === editedTodo
      }">
          <div class="view">
            <input type="checkbox" class="toggle" v-model="todo.completed" />
            <!-- 双击的时候触发，编辑框 -->
            <label @dblclick="editTodo(todo)">{{ todo.title }}</label>
            <button class="destroy" @click="removeTodo(todo)"></button>
          </div>
          <!-- 编辑框 -->
          <input type="text" class="edit" v-if="todo === editedTodo" v-model="todo.title"
            @keyup.enter.ctrl="doneEdit(todo, $event)" @blur="doneEdit(todo, $event)" @keyup.escape="cancelEdit(todo)"
            @vue:mounted="({ el }) => el.focus()" />
        </li>
      </ul>
    </section>
    <!-- 底部 -->
    <footer class="footer">
      <span class="todo-count">
        <span>剩余{{ remaining }}项</span>
      </span>
      <ul class="filters">
        <li>
          <a href="#/all" :class="{ selected: visibility === 'all' }">全部</a>
        </li>
        <li>
          <a href="#/active" :class="{ selected: visibility === 'active' }">未完成</a>
        </li>
        <li>
          <a href="#/completed" :class="{ selected: visibility === 'completed' }">已完成</a>
        </li>
      </ul>
      <button class="clear-completed" @click="removeAllCompleted" v-show="allCompleted">
        清除已完成
      </button>
    </footer>
  </section>
</template>

<script setup>
  import { ref, computed, watch, watchEffect } from "vue";
  //每一项待办事项的结构如下
  //  [{id: 1, title: 'xxx', completed: false}]

  const STORAGE_KEY = 'todo-list'
  //尝试从本地存储中获取数组,如果没有数据则使用空数组（第一次）
  // const todos = ref(JSON.parse(localStorage.getItem(STORAGE_KEY) || '[]'))
  const todos = ref(JSON.parse(localStorage.getItem(STORAGE_KEY)) || [])
  const visibility = ref('all') // 默认是显示所有待办事项

  //接下来我们需要一个过滤器，用于过滤不同状态的待办事项（全部，未完成，已完成）
  const filters = {
    all: (todos) => todos,
    active: (todos) => todos.filter((todo) => !todo.completed),  //未完成
    completed: (todos) => todos.filter((todo) => todo.completed) //已完成
  }

  //接下来，根据当前的状态去调取对应的过滤器函数
  // 如果只有全部的情况，不需要计算属性
  const filteredTodos = computed(() => filters[visibility.value](todos.value))
  const remaining = computed(() => filters.active(todos.value).length)
  //当已完成有值，并且菜单不能是未完成
  const allCompleted = computed(() => filters.completed(todos.value).length > 0 && visibility.value !== 'active')

  function addTodo(e) {
    //拿到用户输入的值
    const value = e.target.value.trim()
    if (value) {
      todos.value.push({ id: Date.now(), title: value, completed: false })
    }
    e.target.value = ""
  }

  //设置监听
  watchEffect(() => {
    //每次todos变化的时候，都需要存储
    localStorage.setItem(STORAGE_KEY, JSON.stringify(todos.value))
  })

  /* 第二部分 */
  // editedTodo 是为了和编辑框进行一个双向绑定
  const editedTodo = ref()  //存储当前编辑的代办事项，没有传递初始值，默认为undefined
  let beforeEditCache = '' // 缓存编辑前的标题，用于取消编辑时恢复

  //编辑
  function editTodo(todo) {
    editedTodo.value = todo
    beforeEditCache = todo.title
  }

  //完成编辑
  function doneEdit(todo, e) {
    //如果原来是编辑模式
    if (editedTodo.value) {
      editedTodo.value = null
      todo.title = e.target.value.trim()  //更新标题
      if (!todo.title) removeTodo(todo) // 如果标题为空，删除此待办事项
    }
  }

  //取消编辑
  function cancelEdit(todo) {
    //退出编辑模式，还原之前的问题
    editedTodo.value = null
    todo.title = beforeEditCache
  }

  function removeTodo(todo) {
    if (window.confirm(`确定要删除此代办事项嘛？`)) {
      // todos.value = todos.value.filter(todo => !todo)
      // todos.value.splice(todos.value.findIndex(todo => todo), 1)
      todos.value.splice(todos.value.indexOf(todo), 1)  //推荐使用indexOf
    } else {
      if (beforeEditCache) {
        todo.title = beforeEditCache
        beforeEditCache = ''
      }
    }
  }

  //根据路由哈希的变化切换visibility
  window.addEventListener('hashchange', onHashChange)
  function onHashChange() {
    console.log(window.location.hash.replace(/#\/?/, ''));
    const route = window.location.hash.replace(/#\/?/, '')
    if (filters[route]) {
      visibility.value = route
    } else {
      visibility.value = 'all'
      window.location.hash = ''
    }
  }
  //初始化
  window.location.hash = ''

  function removeAllCompleted() {
    if (window.confirm('确定要删除所有已完成的待办事项吗？')) {
      // splice的写法太过于复杂
      // filters.completed(todos.value).forEach(todo => { todos.value.splice(todos.value.indexOf(todo), 1) })
      //todos.value = filter过滤后的数据
      todos.value = filters.active(todos.value)
    }

  }
</script>

<style scoped>
  @import url('./assets/todo.css');
</style>